package cn.qicaiwang.open.qxyApi.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class FileOperationUtils {
    private static final Logger logger = LoggerFactory.getLogger(FileOperationUtils.class);


    /**
     * 合并多个JSON文件内容（兼容数组和对象格式）
     */
    public static JSONObject mergeJsonFiles(List<String> filePaths) {
        JSONObject mergedResult = new JSONObject();
        JSONArray mergedArray = new JSONArray();

        filePaths.forEach(filePath -> {
            try {
                String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);

                // 兼容处理JSON数组和对象
                if (content.trim().startsWith("[")) {
                    JSONArray jsonArray = JSON.parseArray(content);
                    mergedArray.addAll(jsonArray);
                } else {
                    JSONObject json = JSON.parseObject(content);
                    mergedArray.add(json);
                }

            } catch (Exception e) {
                logger.error("合并JSON文件失败: {}，内容前100字符: {}",
                        filePath,
                        getFilePreview(filePath, 100),
                        e);
            }
        });

        mergedResult.put("data", mergedArray);
        mergedResult.put("count", mergedArray.size());
        return mergedResult;
    }

    /**
     * 获取文件内容预览（用于错误日志）
     */
    private static String getFilePreview(String filePath, int previewLength) {
        try {
            String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
            return content.length() > previewLength ?
                    content.substring(0, previewLength) + "..." :
                    content;
        } catch (Exception e) {
            return "[无法读取文件内容]";
        }
    }


    /**
     * 下载文件到临时目录
     * @param fileUrl 文件URL
     * @return 下载的临时文件
     * @throws IOException 下载异常
     */
    public static File downloadFile(String fileUrl) throws IOException {
        URL url = new URL(fileUrl);
        String tempDir = System.getProperty("java.io.tmpdir");
        String fileName = getFileNameFromUrl(fileUrl);
        File outputFile = new File(tempDir, fileName);

        try (InputStream in = url.openStream();
             FileOutputStream out = new FileOutputStream(outputFile)) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }
        return outputFile;
    }

    /**
     * 解压ZIP文件
     * @param zipFile ZIP文件
     * @return 解压后的文件列表
     * @throws IOException 解压异常
     */
    public static List<String> unzipFile(File zipFile) throws IOException {
        List<String> fileNames = new ArrayList<>();
        try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile))) {
            ZipEntry entry = zipIn.getNextEntry();

            File destDir = createTempUnzipDir();

            while (entry != null) {
                if (!entry.isDirectory()) {
                    String filePath = destDir + File.separator + entry.getName();
                    extractSingleFile(zipIn, filePath);
                    fileNames.add(entry.getName());
                    logger.info("解压文件: {}", entry.getName());
                }
                zipIn.closeEntry();
                entry = zipIn.getNextEntry();
            }
        }
        return fileNames;
    }

    // 私有辅助方法
    private static String getFileNameFromUrl(String fileUrl) {
        int queryIndex = fileUrl.indexOf('?');
        String path = queryIndex == -1 ? fileUrl : fileUrl.substring(0, queryIndex);
        return path.substring(path.lastIndexOf('/') + 1);
    }

    private static File createTempUnzipDir() {
        String tempDir = System.getProperty("java.io.tmpdir");
        File destDir = new File(tempDir, "unzipped_" + System.currentTimeMillis());
        if (!destDir.exists() && !destDir.mkdir()) {
            throw new RuntimeException("无法创建临时解压目录");
        }
        return destDir;
    }

    private static void extractSingleFile(ZipInputStream zipIn, String filePath) throws IOException {
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) {
            byte[] bytesIn = new byte[4096];
            int read;
            while ((read = zipIn.read(bytesIn)) != -1) {
                bos.write(bytesIn, 0, read);
            }
        }
    }


    public static List<String> unzipToDirectory(File zipFile, String destDir) throws IOException {
        List<String> fileNames = new ArrayList<>();
        try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile))) {
            ZipEntry entry = zipIn.getNextEntry();

            while (entry != null) {
                String filePath = destDir + File.separator + entry.getName();
                if (!entry.isDirectory()) {
                    extractFile(zipIn, filePath);
                    fileNames.add(entry.getName());
                }
                zipIn.closeEntry();
                entry = zipIn.getNextEntry();
            }
        }
        return fileNames;
    }

    private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
        File file = new File(filePath);
        new File(file.getParent()).mkdirs();

        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) {
            byte[] bytesIn = new byte[4096];
            int read;
            while ((read = zipIn.read(bytesIn)) != -1) {
                bos.write(bytesIn, 0, read);
            }
        }
    }
    // 在 FileOperationUtils 中添加
    public static List<Path> unzipAndFilterFiles(File zipFile, Path destDir) throws IOException {
        List<Path> extractedFiles = new ArrayList<>();
        try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile))) {
            ZipEntry entry;
            while ((entry = zipIn.getNextEntry()) != null) {
                if (!entry.isDirectory() && entry.getName().matches(".*\\.json$")) {
                    Path filePath = destDir.resolve(entry.getName());
                    Files.createDirectories(filePath.getParent());
                    Files.copy(zipIn, filePath, StandardCopyOption.REPLACE_EXISTING);
                    extractedFiles.add(filePath);
                }
                zipIn.closeEntry();
            }
        }
        return extractedFiles;
    }

    public static void deleteDirectory(File dir) {
        if (dir.exists()) {
            File[] files = dir.listFiles();
            if (files != null) {
                Arrays.stream(files).forEach(FileOperationUtils::deleteDirectory);
            }
            dir.delete();
        }
    }
}